﻿using System;
using System.Diagnostics;
using System.Reflection;
using System.Windows;
using Mido.Properties;
using Mido.UiModules.ActiveImageModule;
using Mido.UiModules.ScrollBarModule;
using Mido.UiModules.SettingsModule;
using System.Collections.ObjectModel;

namespace Mido.Domain
{
    internal class DomainModel
    {
        private readonly ObservableCollection<ProcessedImage> _images = new ObservableCollection<ProcessedImage>();
        
        private readonly SettingsModel _settings;
        private readonly ScrollBarModel _scrollBarModel;
        private readonly ActiveImageModel _activeImageModel;

        private int _activeImageIndex = -1;

        internal DomainModel()
        {
            _settings = SettingsModel.Load();
            _scrollBarModel = new ScrollBarModel(_images);
            _activeImageModel = new ActiveImageModel(_settings);

			_scrollBarModel.SelectedItemChanged += OnScrollBarSelectedItemChanged;

            _activeImageModel.ShowNextCalled += OnShowNextCalled;
            _activeImageModel.ShowPrivCalled += OnShowPrivCalled;
			_activeImageModel.ExcludeActiveImage += OnExcludeActiveImage;

			_settings.Changed += OnSettingsChanged;
        }

		private void OnScrollBarSelectedItemChanged()
		{
			int index = _images.IndexOf(_scrollBarModel.ActiveImage);
			SelectImage(index);
		}

		private void OnExcludeActiveImage()
		{
			ProcessedImage image = _images[_activeImageIndex];
			OnImageExcludeCall(image);
		}

		private void OnSettingsChanged()
		{
			for (int index = 0; index < _images.Count; index++)
				_images[index].ReloadFullImage();
		}

        private void OnShowPrivCalled()
        {
            SelectImage(_activeImageIndex - 1);
        }

        private void OnShowNextCalled()
        {
            SelectImage(_activeImageIndex + 1);
        }

        internal void SelectImage(int index)
        {
			if (index < 0 || index >= _images.Count)
			{
				_scrollBarModel.ActiveImage = null;
				_activeImageModel.ActiveImage = null;
				return;
			}

            _activeImageIndex = index;

            _scrollBarModel.ActiveImage = _images[_activeImageIndex];
            _activeImageModel.ActiveImage = _images[_activeImageIndex];

            _activeImageModel.IsFirstImage = _activeImageIndex == 0;
            _activeImageModel.IsLastImage = _activeImageIndex == _images.Count - 1;
        }

        internal ObservableCollection<ProcessedImage> Images
        {
            get { return _images; }
        }

        internal SettingsModel Settings
        {
            get { return _settings; }
        }

        internal ScrollBarModel ScrollBarModel
        {
            get { return _scrollBarModel; }
        }

        internal ActiveImageModel ActiveImageModel
        {
            get { return _activeImageModel; }
        }

	    public string Localization
	    {
		    get { return _settings.Localization; }
		    set
		    {
			    if (_settings.Localization == value)
				    return;

				MessageBoxResult result = MessageBox.Show(Application.Current.MainWindow, Resources.DomainModel_Localization_Ask, "Mido",
					MessageBoxButton.YesNo, MessageBoxImage.Question);
				
			    _settings.Localization = value;
				_settings.Save();

			    if (result == MessageBoxResult.Yes)
			    {
				    // restart application
				    Process.Start(Assembly.GetExecutingAssembly().Location);
				    Application.Current.Shutdown();
			    }
		    }
	    }

	    internal void AddImage(ProcessedImage image)
	    {
			image.ExcludeCall += OnImageExcludeCall;
			_images.Add(image);
	    }

		private void OnImageExcludeCall(ProcessedImage image)
		{
			int index = _images.IndexOf(image);
			_images.RemoveAt(index);

			image.ExcludeCall -= OnImageExcludeCall;

			if (index == _activeImageIndex)
				SelectImage(Math.Min(index, _images.Count - 1));
			else 
				SelectImage(_images.IndexOf(ActiveImageModel.ActiveImage));
		}
    }
}
